#include "abstractdao.h"
#include <QString>
#include <QDebug>
#include <QSqlQuery>

//初始化数据库对象
QSqlDatabase abstractDAO::db = QSqlDatabase::addDatabase("QMYSQL");

abstractDAO::abstractDAO()
{
    //头节点
    this->list = new NodeType();
    this->list->SetNext(NULL);

    //初始化数据库信息
    this->db.setDatabaseName("LibraryManageSystem");
    this->db.setHostName("localhost");
    this->db.setUserName("root");
    this->db.setPort(3306);
    this->db.setPassword("li712139");

}

abstractDAO::~abstractDAO()
{
    NodeType* preNode = this->list;
    NodeType* nextNode = this->list;

    while (nextNode != NULL)
    {
        preNode = nextNode;
        nextNode = nextNode->GetNext();

        delete preNode;
    }

    this->list = NULL;
}

void abstractDAO::Clear()
{
    NodeType* preNode = this->list->GetNext();
    NodeType* nextNode = this->list->GetNext();

    while (nextNode != NULL)
    {
        preNode = nextNode;
        nextNode = nextNode->GetNext();

        delete preNode;
    }

    this->length = 0;
    this->list->SetNext(NULL);
}

NodeType* abstractDAO::GetNode(int id)
{
    // 当id为-1时，返回头节点
    if (id == -1)
    {
        return this->list;
    }

    NodeType* node = this->list->GetNext();
    while (node != NULL)
    {
        if (node->GetId() == id)
        {
            return node;
        }

        node = node->GetNext();
    }

    return NULL;
}

void abstractDAO::AddNode(NodeType *node)
{
    if (node == NULL)
    {
        return;
    }

    node->SetNext(this->list->GetNext());
    this->list->SetNext(node);
    this->length++;
}

void abstractDAO::DeleteNode(int id)
{
    NodeType* preNode = this->list;
    NodeType* nextNode = this->list->GetNext();

    while (nextNode != NULL)
    {
        if (nextNode->Compare(id))
        {
            preNode->SetNext(nextNode->GetNext());
            delete nextNode;
            this->length--;
            break;
        }
        else
        {
            preNode = nextNode;
            nextNode = nextNode->GetNext();
        }

    }
}

// abstractDAO只是基类，没有要初始化的信息
// 初始化的具体实现在每一个子类中实现
void abstractDAO::Init()
{

}

void abstractDAO::Save()
{
    NodeType* node = this->GetNode(-1);
    // 当头节点id为1时，表示把链表中的信息添加到数据库中
    // 当有节点id为-1时，表示把链表中的信息从数据库中删掉
    if (node->GetId() == 1)
    {
        this->SaveAdd();
    }
    else if (node->GetId() == -1)
    {
        this->SaveDelete();
    }
}

// 在子类中具体实现
void abstractDAO::SaveAdd()
{

}

// 在子类中具体实现
void abstractDAO::SaveDelete()
{

}

void bookDAO::SaveAdd()
{
    if (!this->db.open()) {
    }

    QString statement;
    QSqlQuery query;
    BookType* node = (BookType*)this->list->GetNext();
    while (node != NULL)
    {
        statement = QString("insert into books (id, name, author, category,"
                            " introduction) values (%1, '%2', '%3', '%4','%5');")
                .arg(node->GetId()).arg(node->GetName()).arg(node->GetAuthor())
                .arg(node->GetCategory()).arg(node->GetIntroduction());
        query.exec(statement);
        node = (BookType*)node->GetNext();
    }

    this->db.close();
}

void bookDAO::SaveDelete()
{
    if (!this->db.open()){
        return;
    }

    QString statement;
    BookType* node = (BookType*)this->list->GetNext();
    QSqlQuery query;
    while (node != NULL)
    {
        statement = QString("delete from books where id = %1;").arg(node->GetId());
        query.exec(statement);
        node = (BookType*)node->GetNext();
    }

    this->db.close();
}

void bookDAO::Init()
{
    if (!this->db.open()) {
        return;
    }
    QSqlQuery query;
    query.exec("select * from books");
    this->length = query.size();
    while (query.next())
    {
        BookType* node = new BookType();
        node->SetId(query.value(0).toInt());
        node->SetName(query.value(1).toString());
        node->SetAuthor(query.value(2).toString());
        node->SetCategory(query.value(3).toString());
        node->SetIntroduction(query.value(4).toString());
        this->AddNode(node);
    }

    this->db.close();
}

void userDAO::Init()
{
    // 打开数据库，如果失败就退出
    if (!this->db.open()){
        return;
    }

    QSqlQuery query;
    query.exec("select * from users");
    this->length = query.size();
    while (query.next()) {
        UserType* node = new UserType();
        node->SetId(query.value(0).toInt());
        node->SetName(query.value(1).toString());
        node->SetPassword(query.value(2).toString());
        this->AddNode(node);
    }

    this->db.close();
}

void userDAO::SaveAdd()
{
    if (!this->db.open()) {
    }

    QString statement;
    QSqlQuery query;
    UserType* node = (UserType*)this->list->GetNext();
    while (node != NULL) {
        statement = QString("insert into users (id, name, password) values "
                            "(%1, '%2', '%3');")
                .arg(node->GetId()).arg(node->GetName()).arg(node->GetPassword());
        query.exec(statement);
        node = (UserType*)node->GetNext();
    }

    this->db.close();
}

void userDAO::SaveDelete()
{
    if (!this->db.open()) {
    }
    QString statement;
    QSqlQuery query;
    UserType* node = (UserType*)this->list->GetNext();
    while (node != NULL)
    {
        statement = QString("delete from users where id = %1;").arg(node->GetId());
        query.exec(statement);
        node = (UserType*)node->GetNext();
    }

    this->db.close();
}
